<template>
  <div>
    <el-upload :action="uploadUrl" :before-upload="handleBeforeUpload" :on-success="handleUploadSuccess"
      :on-error="handleUploadError" name="file" :show-file-list="false" :headers="headers" class="editor-img-uploader"
      v-if="type == 'url'">
      <i ref="uploadRef" class="editor-img-uploader"></i>
    </el-upload>
  </div>
  <div class="editor">
    <quill-editor ref="quillEditorRef" v-model:content="content" contentType="html"
      @textChange="(e) => $emit('update:modelValue', content)" :options="options" :style="styles" />
  </div>
</template>

<script setup>
import { QuillEditor, Quill } from "@vueup/vue-quill";
import "@vueup/vue-quill/dist/vue-quill.snow.css";
import { getToken } from "@/utils/auth";
import { nextTick } from 'vue';
import '@/assets/styles/QuillFont.css'; // 字体和字体大小的自定义文件
import axios from 'axios'
const { proxy } = getCurrentInstance();

const quillEditorRef = ref();
const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/uploadFile"); // 上传的图片服务器地址
const headers = ref({
  Authorization: "Bearer " + getToken()
});

const props = defineProps({
  /* 编辑器的内容 */
  modelValue: {
    type: String,
  },
  /* 高度 */
  height: {
    type: Number,
    default: null,
  },
  /* 最小高度 */
  minHeight: {
    type: Number,
    default: null,
  },
  /* 只读 */
  readOnly: {
    type: Boolean,
    default: false,
  },
  /* 上传文件大小限制(MB) */
  fileSize: {
    type: Number,
    default: 100,
  },
  /* 类型（base64格式、url格式） */
  type: {
    type: String,
    default: "url",
  }
});

// 新增粘贴事件处理
const handlePaste = async (e) => {
  const clipboardItems = e.clipboardData?.items;
  if (!clipboardItems) return;

  for (const item of clipboardItems) {
    if (item.type.indexOf('image') !== -1) {
      e.preventDefault();
      const file = item.getAsFile();
      if (await handleBeforeUpload(file)) { // 复用上传校验
        uploadImageFile(file);
      }
    }
  }
  const quill = quillEditorRef.value.getQuill();
  const range = quill.getSelection();


};
// const handlePaste = async (e) => {
//   const quill = quillEditorRef.value.getQuill();
//   const range = quill.getSelection();
//   if (!range) return;

//   // 保存当前光标位置和编辑器滚动位置
//   const cursorPos = range.index;
//   const scrollContainer = quill.scrollingContainer;
//   const scrollTop = scrollContainer.scrollTop;
//   console.log("保存位置", scrollTop)

//   // 处理图片粘贴（保留原有逻辑）
//   const clipboardItems = e.clipboardData?.items;
//   if (clipboardItems) {
//     for (const item of clipboardItems) {
//       if (item.type.indexOf('image') !== -1) {
//         e.preventDefault();
//         const file = item.getAsFile();
//         if (await handleBeforeUpload(file)) {
//           uploadImageFile(file);
//         }
//         return;
//       }
//     }
//   }

//   // 处理文本粘贴
//   e.preventDefault();

//   // 获取粘贴内容
//   const html = e.clipboardData.getData('text/html');
//   const text = e.clipboardData.getData('text/plain');

//   // 使用Quill的Delta操作精确控制内容插入
//   const delta = html
//     ? quill.clipboard.convert(html)
//     : new Quill.import('delta')().insert(text);

//   // 在保存的光标位置插入内容
//   quill.updateContents(
//     new Quill.import('delta')().retain(cursorPos).concat(delta),
//     'api'
//   );

//   // 确保DOM更新后恢复位置
//   nextTick(() => {
//     console.log("恢复位置", scrollTop)
//     // 恢复光标位置
//     quill.setSelection(cursorPos + text.length, 0, 'api');
//     // 恢复滚动位置
//     scrollContainer.scrollTop = scrollTop;
//   });
// };

function rotateImage(file, orientation) {
  return new Promise((resolve) => {
    const img = new Image();
    const reader = new FileReader();

    reader.onload = (e) => {
      img.src = e.target.result;
      img.onload = () => {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');

        // 根据方向设置canvas尺寸
        if ([5, 6, 7, 8].includes(orientation)) {
          canvas.width = img.height;
          canvas.height = img.width;
        } else {
          canvas.width = img.width;
          canvas.height = img.height;
        }

        // 应用旋转
        switch (orientation) {
          case 2: ctx.transform(-1, 0, 0, 1, canvas.width, 0); break;
          case 3: ctx.transform(-1, 0, 0, -1, canvas.width, canvas.height); break;
          case 4: ctx.transform(1, 0, 0, -1, 0, canvas.height); break;
          case 5: ctx.transform(0, 1, 1, 0, 0, 0); break;
          case 6: ctx.transform(0, 1, -1, 0, canvas.height, 0); break;
          case 7: ctx.transform(0, -1, -1, 0, canvas.height, canvas.width); break;
          case 8: ctx.transform(0, -1, 1, 0, 0, canvas.width); break;
          default: break;
        }

        ctx.drawImage(img, 0, 0);

        // 转换为Blob对象
        canvas.toBlob((blob) => {
          // 创建新的File对象
          const rotatedFile = new File([blob], file.name, {
            type: file.type,
            lastModified: Date.now()
          });
          resolve(rotatedFile);
        }, file.type || 'image/jpeg', 0.9);
      };
    };

    reader.readAsDataURL(file);
  });
}
// 统一上传方法
const uploadImageFile = async (file) => {
  try {
    function fileToBase64(file) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => resolve(reader.result);
        reader.onerror = error => reject(error);
      });
    }

    const base64String = await fileToBase64(file);
    console.log('Base64字符串:', base64String);
    const formData = new FormData();
    // let imgFile = rotateImage(file, 3);
    formData.append('file', file);

    const res = await axios.post(uploadUrl.value, formData, {
      headers: headers.value
    });

    if (res.data.code === 200) {
      insertImageToEditor(res.data.data);
    }
  } catch (error) {
    console.log("error", error)
    proxy.$modal.msgError('图片上传失败');
  }
};

// 统一插入图片逻辑
const insertImageToEditor = (url) => {
  const quill = quillEditorRef.value.getQuill();
  const range = quill.getSelection()?.index || 0;
  quill.insertEmbed(range, 'image', url);
  quill.setSelection(range + 1);

};
// 设置字体大小
const fontSizeStyle = Quill.import('attributors/style/size'); // 引入这个后会把样式写在style上
fontSizeStyle.whitelist = [
  '12px',
  '14px',
  '16px',
  '18px',
  '20px',
  '22px',
  '24px',
  '28px',
  '30px',
];
// 设置字体
const fontStyle = Quill.import('attributors/style/font'); // 引入这个后会把样式写在style上
fontStyle.whitelist = [
  'SimSun', // 宋体
  'SimHei', // 黑体
  'STFANGSO', // 华文仿宋
  'Microsoft-YaHei', // 微软雅黑
  'KaiTi', // 楷体
  'FangSong', // 仿宋
  'STKAITI', // 华文楷体
  'Arial',
  'Times-New-Roman',
  'sans-serif',
];
// const fontSizeStyle = Quill.import('attributors/style/size'); // 引入这个后会把样式写在style上
const options = ref({
  theme: "snow",
  bounds: document.body,
  debug: "warn",
  modules: {
    // 工具栏配置
    toolbar: [
      ["bold", "italic", "underline", "strike"],      // 加粗 斜体 下划线 删除线
      ["blockquote", "code-block"],                   // 引用  代码块
      [{ list: "ordered" }, { list: "bullet" }],      // 有序、无序列表
      [{ indent: "-1" }, { indent: "+1" }],           // 缩进
      [{ script: 'sub' }, { script: 'super' }], // 上标/下标
      [{ direction: 'rtl' }], // 文本方向
      // 增加更多可选择的字号
      [{ size: fontSizeStyle.whitelist }],
      // 增加更多可选择的字体
      [{ font: fontStyle.whitelist }],
      [{ header: [1, 2, 3, 4, 5, 6, false] }],        // 标题
      [{ color: [] }, { background: [] }],            // 字体颜色、字体背景颜色
      [{ align: [] }],                                // 对齐方式
      ["clean"],                                      // 清除文本格式
      ["link", "image"]                      // 链接、图片、视频
    ],
  },
  placeholder: "",
  readOnly: props.readOnly
});
Quill.register(fontSizeStyle, true);
Quill.register(fontStyle, true);

const styles = computed(() => {
  let style = {};
  if (props.minHeight) {
    style.minHeight = `${props.minHeight}px`;
  }
  // if (props.height) {
  //   style.height = `${props.height}px`;
  // }
  style.height = `500px`;
  return style;
});

const content = ref("");
watch(() => props.modelValue, (v) => {
  if (v !== content.value) {
    content.value = v === undefined ? "<p></p>" : v;
  }
}, { immediate: true });

// 如果设置了上传地址则自定义图片上传事件
onMounted(() => {
  if (props.type == 'url') {
    let quill = quillEditorRef.value.getQuill();
    let toolbar = quill.getModule("toolbar");
    toolbar.addHandler("image", (value) => {
      if (value) {
        proxy.$refs.uploadRef.click();
      } else {
        quill.format("image", false);
      }
    });
  }

  // 新增粘贴事件监听
  const editorContainer = quillEditorRef.value.getQuill().root;
  editorContainer.addEventListener('paste', handlePaste);
});

// 上传前校检格式和大小
function handleBeforeUpload(file) {
  const type = ["image/jpeg", "image/jpg", "image/png", "image/svg"];
  const isJPG = type.includes(file.type);
  //检验文件格式
  if (!isJPG) {
    proxy.$modal.msgError(`图片格式错误!`);
    return false;
  }
  // 校检文件大小
  if (props.fileSize) {
    const isLt = file.size / 1024 / 1024 < props.fileSize;
    if (!isLt) {
      proxy.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
      return false;
    }
  }
  return true;
}

// 上传成功处理
function handleUploadSuccess(res, file) {
  // 如果上传成功
  if (res.code == 200) {
    // 获取富文本实例
    let quill = toRaw(quillEditorRef.value).getQuill();
    // 获取光标位置
    let length = quill.selection.savedRange.index;
    // 插入图片，res.url为服务器返回的图片链接地址
    // quill.insertEmbed(length, "image", import.meta.env.VITE_APP_BASE_API + res.fileName);
    quill.insertEmbed(length, "image", res.data);
    // 调整光标到最后
    quill.setSelection(length + 1);
  } else {
    proxy.$modal.msgError("图片插入失败");
  }
}

// 上传失败处理
function handleUploadError() {
  proxy.$modal.msgError("图片插入失败");
}
</script>

<style>
.editor-img-uploader {
  display: none;
}

.editor,
.ql-toolbar {
  white-space: pre-wrap !important;
  line-height: normal !important;
}

.quill-img {
  display: none;
}

.ql-snow .ql-tooltip[data-mode="link"]::before {
  content: "请输入链接地址:";
}

.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
  border-right: 0px;
  content: "保存";
  padding-right: 0px;
}

.ql-snow .ql-tooltip[data-mode="video"]::before {
  content: "请输入视频地址:";
}

.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
  content: "14px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
  content: "10px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
  content: "18px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
  content: "32px";
}

.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: "文本";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  content: "标题1";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  content: "标题2";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  content: "标题3";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  content: "标题4";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  content: "标题5";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  content: "标题6";
}

.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
  content: "标准字体";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
  content: "衬线字体";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
  content: "等宽字体";
}
</style>
